/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package business.dataVisualization.dataProcessing;

import business.algorithm.technicalIndicator.AbstractTechnicalIndicator;
import business.dataVisualization.chart.ChartStyle;
import business.dataVisualization.chart.VisulizationChart;
import dataAccess.databaseManagement.entity.AssetEntity;
import dataAccess.databaseManagement.entity.PriceEntity;
import dataAccess.databaseManagement.manager.PriceManager;
import java.util.*;
import org.jfree.chart.JFreeChart;

/**
 *
 * @author Dinh
 */
public class DataVisualizationProcessor {

    private static PriceManager priceManager = new PriceManager();
    private AssetEntity asset;
    private Date fromDate;
    private Date toDate;
    private int trainingSamplesNumber;
    private ArrayList<AbstractTechnicalIndicator> techIndicatorList = new ArrayList<AbstractTechnicalIndicator>();

    private VisulizationChart visualizationChart;
    private ArrayList<PriceEntity> prices;

    public DataVisualizationProcessor(AssetEntity asset, Date fromDate,
            Date toDate, ChartStyle chartStyle) {
        try {
            this.asset = asset;
            this.fromDate = fromDate;
            this.toDate = toDate;

            updatePricesList();

            visualizationChart = (VisulizationChart) chartStyle.getChartClass().newInstance();
            visualizationChart.initalChart();
            visualizationChart.setPrices(prices);
            visualizationChart.updateChart();
        } catch (InstantiationException ex) {
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
        }
    }

    private void updatePricesList() {
        prices = priceManager.getPriceInInterval(asset.getAssetID(),
                new java.sql.Date(fromDate.getTime()),
                new java.sql.Date(toDate.getTime()));
        Collections.sort(prices, new Comparator<PriceEntity>() {

            @Override
            public int compare(PriceEntity o1, PriceEntity o2) {
                return o1.getDate().compareTo(o2.getDate());
            }
        });
    }

    public void updateChartData() {
        updatePricesList();
        visualizationChart.setPrices(prices);

        // update technical indicator algorithms
        {
            visualizationChart.removeAllPredictionPrice();

            TreeMap<AssetEntity, ArrayList<PriceEntity>> map = new TreeMap<AssetEntity, ArrayList<PriceEntity>>();
            map.put(asset, prices);

            // add new results of Algorithms
            for (AbstractTechnicalIndicator techIndicator : techIndicatorList) {
                techIndicator.setPriceList(map);
                try {
                    visualizationChart.addTechnicalIndicator(techIndicator, techIndicator.runAlgorithm());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }

        visualizationChart.updateChart();
    }

    public void changeChartType(ChartStyle chartStyle) {
        try {
            visualizationChart = (VisulizationChart) chartStyle.getChartClass().newInstance();
            visualizationChart.initalChart();
            this.updateChartData();
        } catch (InstantiationException ex) {
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
        }
    }

    public void addTechIndicator(AbstractTechnicalIndicator abstractTechnicalIndicator) {
        techIndicatorList.add(abstractTechnicalIndicator);
        TreeMap<AssetEntity, ArrayList<PriceEntity>> map = new TreeMap<AssetEntity, ArrayList<PriceEntity>>();
        
        map.put(asset, prices);
        abstractTechnicalIndicator.setPriceList(map);
        try {
            visualizationChart.addTechnicalIndicator(abstractTechnicalIndicator,
                    abstractTechnicalIndicator.runAlgorithm());
        } catch (Exception e) {
            e.printStackTrace();
        }
        visualizationChart.updateChart();
    }
    
    public void removeTechIndicator(AbstractTechnicalIndicator abstractTechnicalIndicator) {
        techIndicatorList.remove(abstractTechnicalIndicator);
        visualizationChart.removeTechnicalIndicator(abstractTechnicalIndicator);
        visualizationChart.updateChart();
    }

    public void removeAllTechIndicator() {
        techIndicatorList.clear();
        visualizationChart.removeAllPredictionPrice();
        visualizationChart.updateChart();
    }
    
    public ArrayList<AbstractTechnicalIndicator> getTechIndicatorList() {
        return techIndicatorList;
    }

    public void setTechIndicatorList(ArrayList<AbstractTechnicalIndicator> techIndicatorList) {
        this.techIndicatorList = techIndicatorList;
    }

    public AssetEntity getAsset() {
        return asset;
    }

    public void setAsset(AssetEntity asset) {
        this.asset = asset;
    }

    public Date getFromDate() {
        return fromDate;
    }

    public void setFromDate(Date fromDate) {
        this.fromDate = fromDate;
    }

    public Date getToDate() {
        return toDate;
    }

    public void setToDate(Date toDate) {
        this.toDate = toDate;
    }

    public JFreeChart getChart() {
        return visualizationChart.getChart();
    }

    public int getTrainingSamplesNumber() {
        return trainingSamplesNumber;
    }

    public void setTrainingSamplesNumber(int trainingSamplesNumber) {
        this.trainingSamplesNumber = trainingSamplesNumber;
    }
}
